"""--------------------------------------------------------------------------------------------------
Filename:   Communicate.py
Author:     Chris Chester
Date:       12 July 2013
Description:
    Class to interface with the Simplex emgStream.exe file to receive sEmg data
    input = module to send the processed data
--------------------------------------------------------------------------------------------------"""


import sys
from subprocess import PIPE, Popen
from threading  import Thread
import time, os
from Queue import Queue, Empty

#===============================================================================
# CLASS: Console
#    Launches and extracts the output from the emgstream software 
#===============================================================================
class Console(): 
    def __init__(self,update_data): 
        '''
        ==============  =====================================
        **Arguments:**
        update_data     The function to send the extracted
                        data to
        ==============  =====================================
        '''
        self._update_data = update_data
        self.ON_POSIX = 'posix' in sys.builtin_module_names
        
        # Kill any previous instances of emgstream running
        self.stop() 
        
        pathName = os.path.dirname(__file__)
        stream = pathName + "\emgstream.exe" 
        self.active = True

        try:
            self.p = Popen([stream], stdout=PIPE, bufsize=1, close_fds=self.ON_POSIX)
        except:
            print ("no emgstream.exe in" + pathName)
        else:
            sys.stdout.write('>> Simplex Connection opened.\n')
            q = Queue()
            
            self.t1 = Thread(target=self.simplex_data_collector,args=(self.p.stdout,q), name='CollectorThread')
            self.t1.daemon = True # thread dies with the program
            self.t1.start()
            
            self.t2 = Thread(target=self.enqueue_output, args=(self.p.stdout,q), name='CommThread')
            self.t2.daemon = True # thread dies with the program
            self.t2.start()
                 
            self.alive = True
            

    def simplex_data_collector(self,output,queue): 
        """
        Collects the data from the given queue and sends it to the 
        previously given update data command
        
        ==============  =====================================
        **Arguments:**
        output            Output stream of signals
        Queue             Queue to extract the data from
        ==============  =====================================
        """     
        while self.active:
            try:  line = queue.get_nowait()
            except Empty:
                isEmpty = True
            else: # got line
                EMGLvl = float(line[:3])
                #print EMGLvl
                self._update_data(EMGLvl)
        
    def enqueue_output(self,output,queue):
        """
        Extracts data from the output of the emgstream file and puts each line
        in the given queue.
        
        ==============  =====================================
        **Arguments:**
        output            Output stream of signals
        Queue             Queue to put data into
        ==============  =====================================
       """ 
        for line in iter(output.readline, b''):
            queue.put(line)
        output.close()
    
    def stop(self):
        """
        Stops the currently running emgstream
        """ 
        try:
            # Force close the emgstream file
            self.p.terminate()
            self.active = False
            
            print "Simplex Connection Closed"
        except:
            alreadyClosed = True


#End of File
